package cn.edu.usst.cs.tomcat_login01;

import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.json.JSONObject;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.*;

@WebServlet(name = "create_account", value = "/account_creator")
public class CreateAccountServlet extends HttpServlet {
    final String TYPE_JSON = "application/json";
    final String TEXT_PLAIN = "text/plain";
    private String message;

    private Set<AccountInfo> accountList;

    public void init() {
        message = "data building";
        accountList = new LinkedHashSet<>();
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {

        response.setContentType("text/html");
        System.out.println("**get***");
        System.out.println(request);
        System.out.println("**get***");

        // Hello
        try (PrintWriter out = response.getWriter()) {
            out.println("<html><body>");
            out.println("<h1>" + message + "</h1>");
            out.println("</body></html>");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String contentType = request.getHeader("Content-Type");
        StringBuilder builder = new StringBuilder();
        Exception exception = null;
        PARSE:
        {
            if (!contentType.equals(TYPE_JSON)) {
                exception=new IllegalArgumentException("""
                        POST请求类型无效，需要是
                        """+TYPE_JSON);
                break PARSE;
            }
            response.setContentType(TEXT_PLAIN);
            try (Scanner scanner = new Scanner(request.getInputStream())) {
                while (scanner.hasNextLine()) {
                    String line = scanner.nextLine();
                    builder.append(line);
                    System.out.println(line);
                }
            }

            JSONObject obj = new JSONObject(builder.toString());

            try {
                AccountInfo appendInfo = new AccountInfo(
                        obj.getString("name"),
                        obj.getString("gender"),
                        obj.getString("password"),
                        obj.getString("password_reenter"),
                        obj.getString("age")
                );
                System.out.println("adding...");
                accountList.add(appendInfo);
            }catch (NumberFormatException e) {
                exception = new RuntimeException("无效年龄: "+e.getLocalizedMessage());
            }
            catch (IllegalArgumentException e) {
                System.out.println("添加信息时出现错误");
                System.out.println(e.getMessage());
                exception = e;
            }
        }
        JSONObject sendOBJ = new JSONObject();
        {
            try {
                System.out.println(accountList.size());
                System.out.println(accountList);
                sendOBJ.put("info", accountList.isEmpty() ?new int[0] :accountList.toString());
            } catch (Exception e) {
                exception = e;
            }
        }

        if(exception!=null){
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            sendOBJ.put("success", false);
            sendOBJ.put("error_description", exception.getLocalizedMessage());
        }else {
            sendOBJ.put("success", true);
        }

        System.out.println(sendOBJ);
        try (PrintWriter out = response.getWriter()) {
            out.println(sendOBJ);
        }
    }

}

class AccountInfo {
    String name;
    String password;
    final String[] genders = {"Male", "Female"};
    String gender;
    int age;

    public AccountInfo(String name, String gender, String password, String password_verify, String age)
            throws IllegalArgumentException
    {
        this.name = name;
        this.gender = gender;
        this.password = password;
        this.age = Integer.parseInt(age);
        if (!password.equals(password_verify)) {
            throw new IllegalArgumentException("两次输入的密码不一致");
        }
        for (String gender_candidate : genders) {
            if (gender_candidate.equals(gender)) {
                this.gender = gender_candidate;
                return;
            }
        }
        throw new IllegalArgumentException("性别无效"+gender);
    }

    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object obj) {
        if(!(obj instanceof AccountInfo)){
            return false;
        }
        return name.equals(((AccountInfo)obj).name);
    }

    @Override
    public String toString() {
        try {
            return toJSON().toString();
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public JSONObject toJSON() throws IllegalAccessException {
        JSONObject obj = new JSONObject();
        for (Field f : this.getClass().getDeclaredFields()) {
            f.setAccessible(true);
            obj.put(f.getName(), f.get(this));
        }
        return obj;
    }
}